// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TouchScreenBase
//
//		Common implementation of a touch screen, among all platforms
//
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef TOUCHSCREEN_TOUCHSCREENBASE_H
#define TOUCHSCREEN_TOUCHSCREENBASE_H

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "Core/IUpdatable.h"
#include "Core/Commons.h"
#include "position2d.h"
#include "rect.h"
#include <list>
#include <map>
#include <string>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define TOUCH_QUEUE_SIZE				(64)
#define TOUCH_QUEUE_EVENT_TOUCH			(0)
#define TOUCH_QUEUE_EVENT_MOVE			(1)
#define TOUCH_QUEUE_EVENT_UNTOUCH		(2)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

typedef enum
{
	E_TOUCH_PRIORITY_LOW,
	E_TOUCH_PRIORITY_NORMAL,
	E_TOUCH_PRIORITY_HIGH,

}E_TouchPriority;

typedef enum
{
	E_TOUCH_STATE_CREATE = 0,
	E_TOUCH_STATE_RELEASE,
	E_TOUCH_STATE_NORMAL,
	E_TOUCH_STATE_TOUCH,
	E_TOUCH_STATE_DISABLE,
	E_TOUCH_STATE_CHANGE,
	E_TOUCH_STATE_HIDE,
}E_TouchState;

typedef enum
{
	E_TouchTarget_Image = 0,
	E_TouchTarget_Text,
}E_TouchTargetType;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class UIAnimPlayer;

class TouchTargetData
{
public:
	TouchTargetData(int x,int y,const char *pName, int msgIndex, E_TouchTargetType type):m_posX(x),m_posY(y),m_groupName(pName),m_messageIndex(msgIndex),m_targetType(type) {};
	TouchTargetData(int x,int y,const char *pName, int msgIndex, E_TouchTargetType type, const char *pFontName, int fontAnchor):m_posX(x),m_posY(y),m_groupName(pName),m_messageIndex(msgIndex),m_targetType(type),m_fontName(pFontName),m_fontAnchor(fontAnchor) {};
	~TouchTargetData() {}

public:
	int m_posX;
	int m_posY;
	std::string m_groupName;
	int m_messageIndex;
	std::string m_fontName;
	int m_fontAnchor;
	E_TouchTargetType m_targetType;
};

class TouchScreenBase : public IUpdatable
{

public:
	typedef long								TouchID;
	typedef short								TouchType;
	typedef irr::core::position2d<TouchType>	TouchPoint;

	struct TouchQueue
	{
		int		type;
		int		x;
		int		y;
		long	id;
		bool    DoubleTap;
	};

	volatile static int						s_touchQueueFirst;
	volatile static int						s_touchQueueLast;
	static struct TouchQueue				s_touchQueue[TOUCH_QUEUE_SIZE];

	static void								AddTouchEvent(int type, int x, int y, long id, bool DoubleTap = false);

// ** Typedefs
// ////////////////////////////////////////////////////////
protected:

	typedef std::list<TouchScreenBase*>		EventReceiverList;
	typedef EventReceiverList::iterator		EventReceiverListIter;
	
	E_TouchPriority	m_touchPriority;

// ** Members
// ////////////////////////////////////////////////////////
protected:
	
	TimeStamp								m_lastUpdateTimestamp;

	//EventReceiverList						m_eventReceivers;
	irr::core::rect<short>					m_rect;


// ** Ctors / Dtor
// ////////////////////////////////////////////////////////
protected:
											TouchScreenBase(E_TouchPriority priority = E_TOUCH_PRIORITY_NORMAL);
public:
	virtual									~TouchScreenBase();
	

	// Events calls
	virtual void							touchBegan(const TouchPoint& point, TouchID touchID, bool isDoubleTap = false);
	virtual void							touchMoved(const TouchPoint& point, TouchID touchID);
	virtual void							touchEnded(const TouchPoint& point, TouchID touchID);
	virtual void							touchCancelled(const TouchPoint& point, TouchID touchID);


	// ** IUpdatable impl.
	void									update(TimeStamp timestamp);

	void									RegisterForEvents(TouchScreenBase* cls);
	void									UnRegisterForEvents(TouchScreenBase* cls);

	void									SetTouchPriority(E_TouchPriority touchPriority) {m_touchPriority = touchPriority;}
	void									ChangeRect(const irr::core::rect<short> &rt);

////////////////////////////////Touch State//////////////////////////////////
protected:
	E_TouchState							m_state;	
public:
	void UpdateTouchState();

	virtual bool IsCreateProcessFinished();
	virtual bool IsExitProcessFinished();
	virtual bool IsExitTouchProcessFinished();
	virtual bool IsExitChangeProcessFinished();
	virtual bool IsShowProcessFinished();
	virtual bool IsEnableProcessFinished();
public:
	virtual void ChangeTouchState( E_TouchState state);
	E_TouchState GetTouchState();

	virtual void Restore();
////////////////////////////////Animation Player//////////////////////////////////
public:
	void SetAnimPlayer(UIAnimPlayer *p);
	UIAnimPlayer * GetAnimPlayer() { return m_pPlayer; }

	bool HasPlayingAnimation();
protected:
	UIAnimPlayer *m_pPlayer;

////////////////////////////////Visible//////////////////////////////////
public:
	bool m_bIsVisible;
public:
	virtual void			SetVisible(bool bVisible);
	virtual bool			IsVisible();

////////////////////////////////Target//////////////////////////////////
protected:
	bool IsExistTargetInfo(E_TouchTargetType targetType, int targetIndex);
	void DrawTarget(E_TouchTargetType targetType,int targetIndex, int x, int y, float rotz, int alpha, float scale);
	void GetTargetPositionInfo(E_TouchTargetType targetType,int targetIndex, int &x, int &y);
public:
	void AddTargetInfo( E_TouchTargetType targetType,int targetIndex ,int x, int y, const char *name, int msgIndex );
	void AddTargetInfo( E_TouchTargetType targetType,int targetIndex ,int x, int y, const char *name, int msgIndex , const char* pFontName,int Anchor);

	void ChangeExistTargetInfo( E_TouchTargetType targetType,int targetIndex ,int x, int y, const char *name, int msgIndex );

private:
	std::map<int, TouchTargetData *> m_allTargetInfos;
protected:
	virtual void DrawImageByTargetData(TouchTargetData *pData, int x, int y, float rotz, int alpha, float scale);
	virtual void DrawTextByTargetData(TouchTargetData *pData, int x, int y, float rotz, int alpha, float scale);
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////